﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Transactions;
using System.Text;
using DAL;
using BOL;
using System.Web;
using System.Web.UI;
using System.IO;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Data.OleDb;
using System.ComponentModel;
using UtilityExtensions;


namespace BOL
{
    [Serializable]
    public class EstructuraCostoBL
    {
        #region "CRUD"

        public int add(dbGestionDataContext _db, string descripcion, int idObra, int idPadre,bool esCajaChica)
        {
            

            EstructuraCosto db = new EstructuraCosto();

            using (TransactionScope ts = new TransactionScope())
            {
                int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());

                db.SetAdd(_db, descripcion, idObra, idEmpleadoEmisor, idPadre,esCajaChica);

                _db.SubmitChanges();
                ts.Complete();
            }
            return db.idInternal;
        }


        //public bool  updateTrans(EstructuraCosto entity, List<EstructuraCostoItem> ecItem, List<EstructuraRecurso> ecrecurso)
        //{

        //    using (TransactionScope ts = new TransactionScope())
        //    {
        //        EstructuraCosto ec = new EstructuraCosto();


        //        foreach (var a in ecItem)
        //        {
        //            EstructuraCostoItem ecitem = new EstructuraCostoItem();

        //            //ecitem.idInternal=a.
        //            ecitem.idEstructuraCosto=a.idEstructuraCosto;
        //            ecitem.idRecurso=a.idRecurso;
        //            ecitem.codigo=a.codigo;
        //            ecitem.descripcion=a.descripcion;
        //            ecitem.unidad=a.unidad;
        //            ecitem.nivel=a.nivel;
        //            ecitem.idPadre=a.idPadre;
        //            ecitem.bitsel=a.bitsel;
        //            ecitem.cantidad=a.cantidad;
        //            ecitem.precio=a.precio;
        //            ecitem.total=a.total;
        //            ecitem.totalMonBase=a.totalMonBase;
        //            ecitem.cantidadUso=a.cantidadUso;
        //            ecitem.totalUso=a.totalUso;
        //            ecitem.idMoneda=a.idMoneda;
        //            ecitem.tipoCambio = a.tipoCambio;


        //        }

        //        //foreach (var b in ecrecurso)
        //        //{
        //        //    EstructuraRecurso ecitem = new EstructuraRecurso();

        //        //    //ecitem.idInternal=a.
        //        //    ecitem.idEstructuraCosto = a.idEstructuraCosto;
        //        //    ecitem.idRecurso = a.idRecurso;
        //        //    ecitem.codigo = a.codigo;
        //        //    ecitem.descripcion = a.descripcion;
        //        //    ecitem.unidad = a.unidad;
        //        //    ecitem.nivel = a.nivel;
        //        //    ecitem.idPadre = a.idPadre;
        //        //    ecitem.bitsel = a.bitsel;
        //        //    ecitem.cantidad = a.cantidad;
        //        //    ecitem.precio = a.precio;
        //        //    ecitem.total = a.total;
        //        //    ecitem.totalMonBase = a.totalMonBase;
        //        //    ecitem.cantidadUso = a.cantidadUso;
        //        //    ecitem.totalUso = a.totalUso;
        //        //    ecitem.idMoneda = a.idMoneda;
        //        //    ecitem.tipoCambio = a.tipoCambio;


        //        //}

        //    }
        //    return true;
        //}


        //public bool update(EstructuraCosto entity,
        //                            DataSet entityList)
        //{
        //    bool result = false;
        //    using (TransactionScope ts = new TransactionScope())
        //    {
        //        DataSet dsDiferencias = new DataSet();

        //        dbGestionDataContext _db =
        //            new dbGestionDataContext(Parametros.strConnString);

        //        EstructuraCosto dbObject;
        //        var q = from p in _db.EstructuraCostos
        //                where p.idInternal == entity.idInternal
        //                select p;



        //        dbObject = q.First();

        //        dbObject.descripcion = entity.descripcion;
        //        dbObject.usuarioMod = entity.usuarioMod;
        //        dbObject.fechaMod = DateTime.Now;


        //        //_db.SubmitChanges();


        //        if (entityList.HasChanges())
        //        {
        //            dsDiferencias.Merge(entityList.GetChanges());

        //            view_EstructuraCostoItem eci = new view_EstructuraCostoItem();
        //            foreach (DataRow drw in dsDiferencias.Tables[eci.GetType().Name].Rows)
        //            {
        //                if (drw.Field<int>("idInternal") ==0)
        //                {
        //                    continue;
        //                }
        //                if (drw.RowState == DataRowState.Modified)
        //                {

        //                    EstructuraCostoItem item =
        //                        _db.EstructuraCostoItems.Single(p => p.idInternal == Convert.ToInt32(drw.Field<int>("IdInternal")));

        //                    //query.First().idComparativo = dbObject.idInternal;

        //                    item.idRecurso = drw.Field<int>("idRecurso");

        //                    item.idEstructuraCosto = entity.idInternal;
        //                    item.codigo = drw.Field<string>("codigo");
        //                    item.descripcion = drw.Field<string>("descripcion");
        //                    item.unidad = drw.Field<string>("unidad");
        //                    item.nivel = drw.Field<Int16>("nivel");
                     
        //                    //item.bitsel = drw.Field<bool>("bitsel");
        //                    item.cantidad = drw.Field<decimal>("cantidad");
        //                    item.precio = drw.Field<decimal>("precio");
        //                    item.total = drw.Field<decimal>("total");
        //                    //item.cantidadSub = drw.Field<decimal>("cantidadSub");
        //                    //item.totalSub = drw.Field<decimal>("totalSub");

        //                    //rerificando sus registros nuevos

        //                    view_ECInsumoItem ec = new view_ECInsumoItem();
        //                    foreach (DataRow drwIns in dsDiferencias.Tables[ec.GetType().Name].Rows)
        //                    {
        //                        if (drw.Field<int>("idInternal") == 0)
        //                        {
        //                            continue;
        //                        }
                                
        //                        if (drwIns.RowState == DataRowState.Modified)
        //                        {
        //                            EstructuraCostoItem itemIns =
        //                              _db.EstructuraCostoItems.Single(p => p.idInternal == Convert.ToInt32(drw.Field<int>("IdInternal")));

        //                            //query.First().idComparativo = dbObject.idInternal;

        //                            itemIns.codigo = drwIns.Field<string>("codigo");
        //                            itemIns.descripcion = drwIns.Field<string>("descripcion");
        //                            itemIns.unidad = drwIns.Field<string>("unidad");
        //                            itemIns.cantidad = drwIns.Field<decimal>("cantidad");
        //                            itemIns.precio = drwIns.Field<decimal>("precio");
        //                            itemIns.total = drwIns.Field<decimal>("total");


        //                        }
        //                        if (drwIns.RowState == DataRowState.Deleted)
        //                        {
        //                            drwIns.RejectChanges();

        //                            EstructuraCostoItem itemIns =
        //                             _db.EstructuraCostoItems.Single(p => p.idInternal == Convert.ToInt32(drwIns.Field<int>("IdInternal")));

        //                            _db.EstructuraCostoItems.DeleteOnSubmit(itemIns);
        //                        }
        //                        if (drwIns.RowState == DataRowState.Added)
        //                        {

        //                            EstructuraCostoItem itemIC = new EstructuraCostoItem();

        //                            itemIC.idPadre = item.idInternal;
        //                            itemIC.idEstructuraCosto = entity.idInternal;
        //                            itemIC.codigo = drwIns.Field<string>("codigo");
        //                            itemIC.descripcion = drwIns.Field<string>("descripcion");
        //                            itemIC.unidad = drwIns.Field<string>("unidad");
        //                            itemIC.nivel = 1;
        //                            itemIC.bitsel = true;
        //                            itemIC.cantidad = drwIns.Field<decimal>("cantidad");
        //                            itemIC.precio = drwIns.Field<decimal>("precio");
        //                            itemIC.total = drwIns.Field<decimal>("total");
        //                            itemIC.cantidadUso = 0;
        //                            itemIC.totalUso = 0;

        //                            item.bitsel = false;

        //                            _db.EstructuraCostoItems.InsertOnSubmit(itemIC);
        //                        }
        //                        _db.SubmitChanges();
        //                    }
        //                    _db.SubmitChanges();

        //                    var qw = from a in _db.EstructuraCostoItems
        //                             where a.idInternal == entity.idInternal
        //                             select a;

        //                    if (qw.Count() > 0)
        //                    {
        //                        item.bitsel = false;
        //                    }
        //                    else
        //                        item.bitsel = true;

        //                    _db.SubmitChanges();

        //                }
        //                if (drw.RowState == DataRowState.Deleted)
        //                {
        //                    drw.RejectChanges();
        //                    //primero sus insumos
        //                    var queryIns = from p in _db.EstructuraCostoItems
        //                                   where p.idPadre == drw.Field<int>("idInternal")
        //                                   select p;

        //                    if (queryIns.Count() > 0)
        //                    {
        //                        _db.EstructuraCostoItems.DeleteAllOnSubmit(queryIns);
        //                    }

        //                    var query = from p in _db.EstructuraCostoItems
        //                                where p.idInternal == drw.Field<int>("idInternal")
        //                                select p;


        //                    if (query.Count() > 0)
        //                        _db.EstructuraCostoItems.DeleteOnSubmit(query.First());

        //                }

        //                if (drw.RowState == DataRowState.Added)
        //                {

        //                    EstructuraCostoItem item = new EstructuraCostoItem();

        //                    item.idRecurso = drw.Field<int>("idRecurso");
        //                    item.idEstructuraCosto = entity.idInternal;
        //                    item.codigo = drw.Field<string>("codigo");
        //                    item.descripcion = drw.Field<string>("descripcion");
        //                    item.unidad = drw.Field<string>("unidad");
        //                    item.nivel = 0;
        //                    item.bitsel = true;
        //                    item.cantidad = drw.Field<decimal>("cantidad");
        //                    item.precio = drw.Field<decimal>("precio");
        //                    item.total = drw.Field<decimal>("total");
        //                    //item.cantidadSub = 0;
        //                    //item.totalSub = 0;
        //                    item.cantidadUso = 0;
        //                    item.totalUso = 0;


        //                    _db.EstructuraCostoItems.InsertOnSubmit(item);

        //                    _db.SubmitChanges();


        //                    view_ECInsumoItem CEitem = new view_ECInsumoItem();


        //                    foreach (DataRow drwIC in dsDiferencias.Tables[CEitem.GetType().Name].Rows)
        //                    {

        //                        if (drw.Field<int>("idInternal") == 0)
        //                        {
        //                            continue;
        //                        }

        //                        if (drwIC.RowState == DataRowState.Added)
        //                        {

        //                            EstructuraCostoItem itemIC = new EstructuraCostoItem();

        //                            itemIC.idPadre = item.idInternal;
        //                            itemIC.idEstructuraCosto = entity.idInternal;
        //                            itemIC.codigo = drwIC.Field<string>("codigo");
        //                            itemIC.descripcion = drwIC.Field<string>("descripcion");
        //                            itemIC.unidad = drwIC.Field<string>("unidad");
        //                            itemIC.nivel = 1;
        //                            itemIC.bitsel = true;
        //                            itemIC.cantidad = drwIC.Field<decimal>("cantidad");
        //                            itemIC.precio = drwIC.Field<decimal>("precio");
        //                            itemIC.total = drwIC.Field<decimal>("total");
                                    
        //                            itemIC.cantidadUso = 0;
        //                            itemIC.totalUso = 0;
        //                            _db.EstructuraCostoItems.InsertOnSubmit(itemIC);
        //                        }
        //                        item.bitsel = false;

        //                    }


        //                    _db.SubmitChanges();

        //                }

        //                //intregridad de informacion  CAb/Det
        //                dbObject.monto = dbObject.getMontoBaseTotal(_db, dbObject.idInternal);
        //                _db.SubmitChanges();
        //            }

        //            ts.Complete();
        //            result = true;
        //        }
        //        return result;
        //    }
        //}
           
          
        public bool delete(int idEstuctura)
        {
           
                bool result=false;
              
                    dbGestionDataContext _db;
                    _db = new dbGestionDataContext(Parametros.strConnString);

                    EstructuraCosto dbObject;

                   

                    var q = from p in _db.EstructuraCostos
                            where p.idInternal == idEstuctura
                            select p;

                    dbObject = q.First();

                    if (dbObject.montoUso > 0)
                    {
                        throw new Exception("No puede eliminar el recurso en comparativo");
                    }

                    if (dbObject.monto > 0)
                    {
                        throw new Exception("No puede eliminar el recurso configurados");
                    }

                    var det = from r in _db.EstructuraCostoItems
                              where r.idEstructuraCosto == idEstuctura
                            select r;

                    
                    
                    _db.EstructuraCostoItems.DeleteAllOnSubmit(det);
                                       
                    _db.EstructuraCostos.DeleteOnSubmit(dbObject);
                    using (TransactionScope ts = new TransactionScope())
                    {

                    _db.SubmitChanges();
                    ts.Complete();
                    result = true;
                }
                return result;
           
        }


        public EstructuraCostoInfo Load(int idEstructuraCosto)
        {
            return (from a in DbUtil.Db.EstructuraCostos
                    where a.idInternal == idEstructuraCosto
                    select new EstructuraCostoInfo(a.idInternal,
                        a.descripcion,
                        a.monto.Value,
                        a.montoUso.Value,
                        a.nivel.Value,
                        a.idObra.Value,
                        a.idMoneda.Value,
                        a.Moneda.simbol,
                        a.tipoCambio.Value)).First() ;
        }

        #endregion



        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public EstructurCostoItemTotalInfo GetEstructuraCostoItemTotales(Obra obra ,int idEstructuracosto)
        {

            EstructurCostoItemTotalInfo info = new EstructurCostoItemTotalInfo();
            
            bool incluyeIGV = obra.incluyeIGV.Value;
            decimal tipoCambio = obra.tipoCambio.Value;

            //BASE S/.
            var baseSoles = (from a in DbUtil.Db.EstructuraCostoItems
                             where a.idEstructuraCosto == idEstructuracosto
                                   & a.idMoneda == 3
                                   & a.idRecurso != null
                                   & a.nivel == 0
                             select a);
           
            var baseDollar = (from a in DbUtil.Db.EstructuraCostoItems
                              where a.idEstructuraCosto == idEstructuracosto
                                      & a.idRecurso != null
                                    & a.nivel == 0
                                    & a.idMoneda == 4
                              select a);


            var usoSoles = (from a in DbUtil.Db.OrdenCompras
                            where 
                            a.idEstructuraCompras == idEstructuracosto
                            & a.bitActivo==true
                            & a.idMoneda == 3
                            select a);

            var usoDollar = (from a in DbUtil.Db.OrdenCompras
                              where 
                              a.idEstructuraCompras== idEstructuracosto
                              & a.bitActivo==true
                              & a.idMoneda == 4
                              select a);
         
            decimal solesBASE = 0;
            decimal solesBASEToDollar = 0;
            decimal solUso = 0;
            decimal solUsoToDollar = 0;

            //soles
            if (baseSoles.Count() > 0)
            {
                solesBASE = baseSoles.Sum(p => p.Recurso.parcialUso.Value);
                solesBASEToDollar = baseSoles.Sum(p => p.Recurso.parcialUso.Value) / tipoCambio;
            }
            //dollar

            if (baseDollar.Count() > 0)
            {
                solesBASE = solesBASE + baseDollar.Sum(p => p.Recurso.parcialUso.Value) * tipoCambio;
                solesBASEToDollar = solesBASEToDollar + baseDollar.Sum(p => p.Recurso.parcialUso.Value);
            }


            //----------------------------
            //soles
            if (usoSoles.Count() > 0)
            {
                solUso = (incluyeIGV==true? usoSoles.Sum(p => p.total.Value): usoSoles.Sum(p => p.subTotal.Value));
                solUsoToDollar = incluyeIGV == true ? usoSoles.Sum(p => p.total.Value) / tipoCambio : usoSoles.Sum(p => p.subTotal.Value) / tipoCambio;
            }
            //dollar

            if (usoDollar.Count() > 0)
            {
                solUso = solUso + (incluyeIGV == true ? usoDollar.Sum(p => p.total.Value) * tipoCambio : usoDollar.Sum(p => p.subTotal.Value) * tipoCambio);
                solUsoToDollar = (incluyeIGV == true ? solUsoToDollar + usoDollar.Sum(p => p.total.Value) : usoDollar.Sum(p => p.subTotal.Value));
            }
           
            info.estructuraCostoBaseSoles = String.Format("S/. {0:N}", solesBASE);
            info.estructuraCostoBaseDollar = String.Format("$ {0:N}", solesBASEToDollar);
            info.estructuraCostoUsoSoles = String.Format("S/. {0:N}", solUso);
            info.estructuraCostoUsoDollar = String.Format("$ {0:N}", solUsoToDollar);
            info.estructuraCostoDispSoles = String.Format("S/. {0:N}", solesBASE - solUso);
            info.estructuraCostoDispDollar = String.Format("$ {0:N}", solesBASEToDollar - solUsoToDollar);

            return info;
        }


        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public EstructurCostoTotalInfo GetEstructuraCostoTotales( Obra obra)
        {

            EstructurCostoTotalInfo info = new EstructurCostoTotalInfo();
            
            bool incluyeIGV = obra.incluyeIGV.Value;
            decimal tipoCambio = obra.tipoCambio.Value;

            var q = from a in DbUtil.Db.Presupuesto
                    where a.idObra == obra.idInternal
                    select a;
            var w = from b in DbUtil.Db.EstructuraCostoItems
                    where b.EstructuraCosto.idObra == obra.idInternal
                    & b.idRecurso!=null
                    select b;
            var oc = from e in DbUtil.Db.OrdenCompras
                     where e.idObra == obra.idInternal
                     & e.bitActivo==true
                     select e;
            info.presupuestoSoles = String.Format("S/. 0.00");
            info.presupuestoDollar = String.Format("$  0.00");

            if (q.Count() > 0)
            {
                decimal totalpre = 0;
                decimal totalpreDLL = 0;
                decimal? soles = q.Where(p => p.idMoneda == 3).Sum(p => p.monto);
                decimal? solesDLL = q.Where(p => p.idMoneda == 3).Sum(p => p.monto / tipoCambio);  // lo convierto en DOLAR

                if (soles.HasValue)
                    totalpre = soles.Value;
                if (solesDLL.HasValue)
                    totalpreDLL = solesDLL.Value;


                decimal? dolares = q.Where(p => p.idMoneda == 4).Sum(p => p.monto * tipoCambio);       // lo converto en soles
                decimal? dolaresDLL = q.Where(p => p.idMoneda == 4).Sum(p => p.monto);

                if (dolares.HasValue)
                    totalpre = totalpre + dolares.Value;

                if (dolaresDLL.HasValue)
                    totalpreDLL = totalpreDLL + dolaresDLL.Value;
                //----dolares

                info.presupuestoSoles = String.Format("S/. {0:N}", totalpre);
                info.presupuestoDollar = String.Format("$. {0:N}", totalpreDLL);

               
            }
            info.estructuraItemSoles = String.Format("S/. 0.00");
            info.estructuraItemDollar = String.Format("$ 0.00");

            if (w.Count() > 0)
            {

                //siempre se encuertra en soles
                info.estructuraSoles=w.Sum(p => (p.total*p.tipoCambio)).Value;
                info.estructuraItemSoles = String.Format("S/. {0:N}", info.estructuraSoles);

                // para los dolares /sumamos en partes 
                 var resul=w.Where(p=>p.idMoneda==3).Count()>0?
                     w.Where(p => p.idMoneda == 3).Sum(p => p.total.Value / tipoCambio) : 0;

                info.estructuraDollar=resul + (w.Where(p=>p.idMoneda==4).Count()>0?w.Where(p=>p.idMoneda==4).Sum(p=>p.total.Value):0);
                info.estructuraItemDollar = String.Format("$ {0:N}", info.estructuraDollar);
             
            }

            info.estructuraItemUsoSoles = String.Format("S/. 0.00");
            info.estructuraItemUsoDollar = String.Format("$ 0.00");

            if (oc.Count() > 0)
           {

                    info.ordenCompraSoles=(incluyeIGV==true? oc.Sum(p => (p.total * p.tipoCambio)).Value:oc.Sum(p => (p.subTotal * p.tipoCambio)).Value);
                    info.estructuraItemUsoSoles = String.Format("S/. {0:N}", info.ordenCompraSoles);

               // para los dolares /sumamos en partes 
                var resul = oc.Where(p => p.idMoneda == 3).Count() > 0 ? (incluyeIGV == true ? oc.Where(p => p.idMoneda == 3).Sum(p => p.total.Value / tipoCambio) : oc.Where(p => p.idMoneda == 3).Sum(p => p.subTotal.Value / tipoCambio)) : 0;

                info.ordenCompraDollar=resul + 
                   (oc.Where(p => p.idMoneda == 4).Count() > 0 ? (incluyeIGV == true ? oc.Where(p => p.idMoneda == 4).Sum(p => p.total.Value):oc.Where(p => p.idMoneda == 4).Sum(p => p.subTotal.Value)) : 0);
                info.estructuraItemUsoDollar = String.Format("$ {0:N}", info.ordenCompraDollar);
               
           }

            return info;
        }

        public IEnumerable<EstructuraCostoListInfo> GetEstructuraCosto(int idObra,int idEstructura)
        {
            //--bool  incluyeIGV=DbUtil.Db.Obras.Single(p=>p.idInternal==idObra).incluyeIGV.Value;
            var obra = DbUtil.Db.Obras.Single(p => p.idInternal == idObra);

            var q = (from a in DbUtil.Db.EstructuraCostos
                    where a.idObra == idObra
                    & (idEstructura == 0 ? a.idPadre != idEstructura : a.idPadre == idEstructura)
                    select new EstructuraCostoListInfo

                     {
                         descripcion = a.descripcion.ToUpper(),
                         idInternal = a.idInternal,
                         idObra = a.idObra.Value,
                         idPadre = a.idPadre,
                         moneda = a.Moneda,
                         //todo los  recursos involucrados del proyecto.
                         montoBase = a.EstructuraCostoItems.Where(t => t.idRecurso != null).Count() > 0 ?
                                              (a.EstructuraCostoItems.Where(y => y.idRecurso != null).Sum(p => p.Recurso.parcialUso.Value * p.tipoCambio.Value)) :
                                              0,
                         // todos los montos involucrados en el proyecto.
                         montoOCUso = a.OrdenCompras.Where(i => i.bitActivo == true).Count() > 0 ?
                                             obra.incluyeIGV.Value== true
                                            ?a.OrdenCompras.Where(i => i.bitActivo == true).Sum(r => r.total.Value * (r.idMoneda==4?obra.tipoCambio.Value:1)) :
                                            a.OrdenCompras.Where(i => i.bitActivo == true).Sum(r => r.subTotal.Value * (r.idMoneda == 4 ? obra.tipoCambio.Value : 1)) 
                                            : 0,

                     }).OrderBy(p=>p.descripcion);
            return q; 


        }
        public List<RecursoECItemInfo> GetRecursoEstructuraCostoItem(int idestructuraCosto)
        {
            var q= (from a in DbUtil.Db.EstructuraCostoItems
                    where a.idEstructuraCosto == idestructuraCosto
                    & a.idRecurso!=null
                    select new RecursoECItemInfo
                        {
                            idRecurso=a.idRecurso.Value,
                            presupuesto=a.Recurso.Partida.Presupuesto.abreviacion,
                            partida=a.Recurso.Partida.codigo,
                            codigo=a.codigo,
                            descripcion=a.descripcion,
                            idInternal=a.idInternal,
                            precio=string.Format("{0} {1:N}",a.Moneda.simbol,a.precio.Value),
                            total=string.Format("{0} {1:N}",a.Moneda.simbol,a.Recurso.parcialUso.Value),
                            unidad=a.unidad,
                            cantidad=string.Format("{0:N}",a.cantidad.Value),
                        });

            

            return q.ToList();

        }
        public int addECItemFromRecurso(int idEstructuraCosto, int idRecurso)
        {
            int id=0;

            int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());

            using (TransactionScope ts = new TransactionScope())
            {

                dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString);

                EstructuraCosto dbEC = _db.EstructuraCostos.Single(p => p.idInternal == idEstructuraCosto);
                Recurso dbRecurso = _db.Recursos.Single(p => p.idInternal == idRecurso);
                //Empleado dbEmpleado=_db.Empleado.Single(p=>p.idInternal==idUsuario);

                EstructuraCostoItem ecitem = new EstructuraCostoItem();
                if ((dbRecurso.parcial - dbRecurso.parcialUso) >= 0)
                {
                    id = ecitem.addECItemFromRecurso(_db,
                        idEstructuraCosto,
                        dbRecurso,
                        idEmpleadoEmisor);

                    // Totalizadores;
                    dbRecurso.updateUso(_db);
                    dbEC.updateMontoMonBase(_db);
                }

                ts.Complete();
                //}

            }
            return id;
            }
     


        public bool dividirECitem(int idEstructuraCostoItem,
            List<EstructuraCostoitemsingleInfo> ECitemList
            )
        {
            dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString);
            EstructuraCosto ec = new EstructuraCosto();
            EstructuraCostoItem dbECItemPadre = new EstructuraCostoItem();
            Recurso recurso = new Recurso();

            EstructuraCostoItem dbECitem = _db.EstructuraCostoItems.Single(p => p.idInternal == idEstructuraCostoItem);


            int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());

            //no se puede dividir si se encuentra utilizado


            var qc = from a in _db.ComparativoItems
                     where a.idEstructuraCostoItem == idEstructuraCostoItem
                     select a;
            if (qc.Count() > 0)
            {
                throw new Exception("No se puede detallar el recurso por encontrarse  utilizado en comparativo");

            }
            
            using (TransactionScope ts = new TransactionScope())
            {
                //el  padre se deshabilita
                dbECitem.bitsel = false;

                foreach (EstructuraCostoitemsingleInfo item in ECitemList)
            {
                if (item.idInternal == 0)
                {
                    continue;
                }
                EstructuraCostoItem dbECitemdiv = new EstructuraCostoItem();

                dbECitemdiv.addECItem(_db,
                    dbECitem.idEstructuraCosto.Value,
                    null,
                    item.idInsumo,
                    item.codigo,
                    item.descripcion,
                    item.unidad,
                    Convert.ToInt16(dbECitem.nivel + 1),
                    dbECitem.idInternal,
                    true,
                    item.cantidad,
                    item.precio,
                    item.total,
                    dbECitem.idMoneda,
                    dbECitem.tipoCambio,
                    null,
                    idEmpleadoEmisor,
                    null);
            }

            
            // actualizamos el total de estructura de costos
            
                        //-------------------------------

                _db.SubmitChanges();
                if (dbECitem.nivel == 0)
                {
                    dbECitem.updatePadreDetallado(_db, idEmpleadoEmisor);
                    
                    ec = _db.EstructuraCostos.Single(p => p.idInternal == dbECitem.idEstructuraCosto);
                    ec.updateMontoMonBase(_db);

                     
                     
                    recurso = _db.Recursos.Single(p => p.idInternal == dbECitem.idRecurso);
                    recurso.updateUso(_db);
                     
                    

                }
                if (dbECitem.nivel == 1)
                {

                    dbECitem.updatePadreDetallado(_db, idEmpleadoEmisor);
                    
                    dbECItemPadre = _db.EstructuraCostoItems.Single(p => p.idInternal == dbECitem.idPadre);
                    dbECItemPadre.updatePadreDetallado(_db, idEmpleadoEmisor);
                    
                    
                    ec = _db.EstructuraCostos.Single(p => p.idInternal == dbECitem.idEstructuraCosto);
                    ec.updateMontoMonBase(_db);

                    recurso = _db.Recursos.Single(p => p.idInternal == dbECItemPadre.idRecurso);
                    recurso.updateUso(_db);
                }

            
                
               ts.Complete();
            }
            return true;          
        }

#region "Agrupado"
        public bool addECItemAgrupado(
                                    int idEstructuraCosto,
                                    int idMoneda,
                                    int idObra,
                                    List<EstructuraCostoItemRecursoInfo> ECItemList,
                                    List<EstructuraCostoitemsingleInfo> InsumosList)
        {

            decimal totalRecurso = ECItemList.Sum(p => p.total);
            decimal totalNewRecurso = InsumosList.Sum(p => p.total);
          

            if (totalRecurso <= 0)
            {
                throw new Exception("No existe recursos");
            }

            if (Math.Round(totalRecurso) != Math.Round(totalNewRecurso))
            {
                throw new Exception("Los montos de los nuevos recursos generados  son diferentes  ");
            }

            using (TransactionScope ts = new TransactionScope())
            {
                dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString);
                // como la ECItemList se encuentra ya registrado en la estructura  solo actualizamos 
                // su estado a no seleccionable , verificamos que este en  nivel=0 y
                //y si id de transaccion de  origenid, el id padre debe ser null
                // creamos el control de numeracion de tabla de agrupados

                int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());
               

                //1 creamos el id de transaccion de agrupado
                EstructuraAgrupado ECA = new EstructuraAgrupado();
                ECA.idMoneda = idMoneda;
                ECA.idEstructuraCosto = idEstructuraCosto;
                ECA.fechaCre = DateTime.Now;
                ECA.usuarioCre = idEmpleadoEmisor;
                ECA.idOrigen = 1;// indica que es desde los presupuesto
                ECA.idObra = idObra;
               
             

               
                _db.EstructuraAgrupados.InsertOnSubmit(ECA);
                _db.SubmitChanges();

                foreach (EstructuraCostoItemRecursoInfo item in ECItemList)
                {

                    if (item.idInsumo == 12954)
                    {
                        //notas de credito
                        continue;
                    }

                    EstructuraCostoItem itemdb =
                        _db.EstructuraCostoItems.Single(p => p.idInternal == item.idInternal);

                    if (itemdb.idPadre != null | itemdb.nivel != 0)
                    {
                        throw new Exception(" El recurso no puede ser  recurso detallado");

                    }

                    if (itemdb.total <= (itemdb.EstructuraAgrupadoItems.Count>0?itemdb.EstructuraAgrupadoItems.Sum(p=>p.total):0))
                    {
                        throw new Exception(" El recurso se encuentra agrupado verifique");

                    }
                    itemdb.bitsel = false;
                    itemdb.idAgrupadoOrigen = ECA.idInternal;

                    EstructuraAgrupadoItem itemAgrupado = new EstructuraAgrupadoItem();
                    itemAgrupado.idEstructuraCostoItem = item.idInternal;
                    itemAgrupado.idEstructuraagrupado = ECA.idInternal;
                    itemAgrupado.total = item.total;
                    _db.EstructuraAgrupadoItems.InsertOnSubmit(itemAgrupado);

                }
                //todo las estructuras tiene el tipode cambio de la obra
                //registramos si existe la nota de credito
                var itemNC = ECItemList.Where(p => p.idInsumo == 12954);
                if  (itemNC.Count()>0)
                {
                    var ie=itemNC.First();
                    EstructuraCostoItem nuevo = new EstructuraCostoItem();
                    nuevo.addECItem(_db,idEstructuraCosto,null,ie.idInsumo,ie.codigo,ie.descripcion,ie.unidad,0,null,false,ie.cantidad,
                                    ie.precio,ie.total,ie.moneda.idInternal,ie.tipoCambio,null,1,null);
                    nuevo.idAgrupadoOrigen = ECA.idInternal;
                    EstructuraAgrupadoItem itemAgrupado = new EstructuraAgrupadoItem();
                    itemAgrupado.idEstructuraCostoItem = nuevo.idInternal;
                    itemAgrupado.idEstructuraagrupado = ECA.idInternal;
                    itemAgrupado.total = nuevo.total.Value;
                    _db.EstructuraAgrupadoItems.InsertOnSubmit(itemAgrupado);

                }


                _db.SubmitChanges();

                foreach (EstructuraCostoitemsingleInfo itemNew in InsumosList)
                {
                    //actualizamos los valores de  la transaccion
                    if (itemNew.idInternal == 0)
                    {
                        continue;
                    }
                    EstructuraCostoItem ECItem = new EstructuraCostoItem();
                    ECItem.setTCFromMoneda(_db,idMoneda,idObra);
                    
                    decimal tipoCambio=ECItem.tipoCambio.Value;
                    
                    ECItem.addECItem(_db,
                                                            idEstructuraCosto,
                                                            null,
                                                            itemNew.idInsumo,
                                                            itemNew.codigo,
                                                            itemNew.descripcion,
                                                            itemNew.unidad,
                                                            0,
                                                            null,
                                                            true,
                                                            itemNew.cantidad,
                                                            itemNew.precio,
                                                            itemNew.total,
                                                            idMoneda,
                                                            tipoCambio,
                                                             ECA.idInternal,
                                                             idEmpleadoEmisor,
                                                             itemNew.idOrdenCompraItem == 0 ? null : itemNew.idOrdenCompraItem.ToInt2());

                }
               _db.SubmitChanges();
                ts.Complete();
                return true;
            }
            }





        int _count;
        public int Count(int idEstructuraCosto, int idOrigen, int startRowIndex, int maximumRows, string sortExpression)
        {
            return _count;
        }

        private IQueryable<EstructuraCostoItemAgrupadoListInfo> ApplySort(IQueryable<EstructuraCostoItemAgrupadoListInfo> q, string sortExpression)
        {
            switch (sortExpression)
            {
                case "idInternal":
                    q = q.OrderBy(b => b.idInternal);
                    break;
                case "idInternal DESC":
                    q = q.OrderByDescending(b => b.idInternal);
                    break;
                case "fecha":
                    q = q.OrderBy(b => b.fecha);
                    break;
                case "fecha DESC":
                    q = q.OrderByDescending(b => b.fecha);
                    break;
                case "total":
                    q = q.OrderBy(b => b.total);
                    break;
                case "total DESC":
                    q = q.OrderByDescending(b => b.total);
                    break;

               

                default:
                    q = q.OrderByDescending(b => b.idInternal);
                    break;
            }
            return q;
        }


        private IQueryable<EstructuraCostoItemConfInfo> ApplySort(IQueryable<EstructuraCostoItemConfInfo> q, string sortExpression)
        {
            switch (sortExpression)
            {
                case "idInternal":
                    q = q.OrderBy(b => b.idInternal);
                    break;
                case "idInternal DESC":
                    q = q.OrderByDescending(b => b.idInternal);
                    break;
                case "codigo":
                    q = q.OrderBy(b => b.codigo);
                    break;
                case "codigo DESC":
                    q = q.OrderByDescending(b => b.codigo);
                    break;
                case "descripcion":
                    q = q.OrderBy(b => b.descripcion);
                    break;
                case "descripcion DESC":
                    q = q.OrderByDescending(b => b.descripcion);
                    break;

                case "total":
                    q = q.OrderBy(b => b.total);
                    break;
                case "total DESC":
                    q = q.OrderByDescending(b => b.total);
                    break;

                case "totalDisp":
                    q = q.OrderBy(b => b.totalDisp);
                    break;
                case "totalDisp DESC":
                    q = q.OrderByDescending(b => b.totalDisp);
                    break;
                case "unidad":
                    q = q.OrderBy(b => b.unidad);
                    break;
                case "unidad DESC":
                    q = q.OrderByDescending(b => b.unidad);
                    break;

                default:
                    q = q.OrderByDescending(b => b.idInternal);
                    break;
            }
            return q;
        }


         [DataObjectMethod(DataObjectMethodType.Select, false)]
        public IEnumerable<EstructuraCostoItemAgrupadoListInfo> GetAgrupadoList(int idEstructuraCosto, int idOrigen, int startRowIndex, int maximumRows, string sortExpression)
        {

            var q = from a in DbUtil.Db.EstructuraAgrupados
                where a.idEstructuraCosto == idEstructuraCosto &
                a.idOrigen == idOrigen
                select new EstructuraCostoItemAgrupadoListInfo
                {

                    idInternal = a.idInternal,
                    fecha = a.fechaCre.Value,
                    total=a.EstructuraCostoItems.Sum(u=>u.total.Value),
                    totalStr=string.Format("{0} {1:N}",
                                a.EstructuraCostoItems.First().Moneda.simbol,
                                a.EstructuraCostoItems.Sum(u=>u.total.Value)),
                    fechaStr = a.fechaCre.Value.ToShortDateString(),
                    origen = a.EstructuraAgrupadoItems.Select(p=>(string.Format("{0}-{1}",p.EstructuraCostoItem.codigo,p.EstructuraCostoItem.descripcion))),
                    destino = a.EstructuraCostoItems.Select(p => (string.Format("{0}-{1} /Disponible:{2}", p.codigo, p.descripcion,string.Format("{0:N}",p.total-p.totalUso-p.totalReUso)))),
                 };

          
            _count = q.Count();
           
            
            q = ApplySort(q, sortExpression);
            return q.Skip(startRowIndex).Take(maximumRows).ToList();

          


        }
#endregion


      
        public bool deleteECItemAgrupado(
            int idAgrupado)
        {
            using (TransactionScope ts = new TransactionScope())
            {

                dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString);

                //Eliminamos los  item  generados  en la estructura
                var destino = from a in _db.EstructuraCostoItems
                              where a.idAgrupadoDestino == idAgrupado
                              select a;

                //Eliminamos la estructura 
                foreach (EstructuraCostoItem item in destino)
                {

                    //Verificamos que no este en  usado los item agrupados
                    var comitem = from a in _db.ComparativoItems
                                  where a.idEstructuraCostoItem == item.idInternal
                                  select a;
                    //verificar si existe comparativos con este ECItem
                    if (comitem.Count() > 0)
                    {

                        throw new Exception("No se puede Eliminar el recurso por encontrarse  utilizado");
                    }

                    //si este fue agrupado para formar otro  recurso
                    if (item.idJuntoPadre != null)
                    {
                        throw new Exception("No se puede Eliminar el recurso por encontrarse  agrupado a otros recursos  del mismo codigo en recursos configurados");
                    }

                    // verificamos que sus hijos y nietos no esten utilizados //por regla solo dos niveles
                    var hijos = from a in _db.EstructuraCostoItems
                                where a.idPadre == item.idInternal
                                select a;
                    foreach (var a in hijos)
                    {
                        if (a.totalUso > 0)
                        {
                            throw new Exception("No se puede Eliminar el recurso por encontrarse  utilizado");
                        }
                        //si este fue agrupado para formar otro  recurso
                        if (a.idJuntoPadre != null)
                        {
                            throw new Exception("No se puede Eliminar el recurso por encontrarse  agrupado a otros recursos  del mismo codigo en recursos configurados");
                        }

                        var nietos = from b in _db.EstructuraCostoItems
                                     where b.idPadre == a.idInternal
                                     select b;

                        foreach (var b in nietos)
                        {
                            if (b.totalUso > 0)
                            {
                                throw new Exception("No se puede Eliminar el recurso por encontrarse  utilizado");
                            }
                            //si este fue agrupado para formar otro  recurso
                            if (a.idJuntoPadre != null)
                            {
                                throw new Exception("No se puede Eliminar el recurso por encontrarse  agrupado a otros recursos  del mismo codigo en recursos configurados");
                            }


                            _db.EstructuraCostoItems.DeleteOnSubmit(b);
                        }
                        _db.EstructuraCostoItems.DeleteOnSubmit(a);
                    }
                    //finalmente eliminamos La estructura
                    _db.EstructuraCostoItems.DeleteOnSubmit(item);
                    _db.SubmitChanges();
                }
                //tramemos los originales
                //---------------------------------
                var origen = (from e in _db.EstructuraAgrupadoItems
                             where e.idEstructuraagrupado == idAgrupado
                             select e.EstructuraCostoItem).ToList();

              //-----------------------------------------

                var qitem = from a in _db.EstructuraAgrupadoItems
                            where a.idEstructuraagrupado == idAgrupado
                            select a;

                
                _db.EstructuraAgrupadoItems.DeleteAllOnSubmit(qitem);
                _db.SubmitChanges();

                //---------------------------actulizamos los originales

                


                 foreach (EstructuraCostoItem itemdb in origen)
                 {
                     EstructuraCostoItem e = _db.EstructuraCostoItems.Single(p => p.idInternal == itemdb.idInternal);
                     e.bitsel = true;
                     e.idAgrupadoOrigen = null;
                     _db.SubmitChanges();
                 }
                 var NC = origen.Where(p => p.idInsumo == 12954);
                 if (NC.Count() > 0)
                 {
                     foreach (var item in NC)
                     {
                            //eliminamos del sistem
                         var ECITEM = _db.EstructuraCostoItems.Single(p => p.idInternal == item.idInternal);
                         _db.EstructuraCostoItems.DeleteOnSubmit(ECITEM);

                     }
                     _db.SubmitChanges();

                 }



                 EstructuraAgrupado agrupado = _db.EstructuraAgrupados.Single(p => p.idInternal == idAgrupado);
                 _db.EstructuraAgrupados.DeleteOnSubmit(agrupado);
                 _db.SubmitChanges();

                ts.Complete();

                return true;
            }

        }


        public bool addECItemReAgrupado(
                                    int idEstructuraCosto,
                                    int idMoneda,
                                    int idObra,
                                    List<EstructuraCostoitemReUsoInfo> reUsoComparativoItemList,
                                    List<EstructuraCostoitemsingleInfo> newECItemList)
        {

            decimal totalOrigen = reUsoComparativoItemList.Sum(p => p.totalReUso);
            decimal totalNewRecurso = newECItemList.Sum(p => p.total);

            dbGestionDataContext _db = new dbGestionDataContext(DbUtil.strConnString); 
            if (totalOrigen <= 0)
            {
                throw new Exception("No existe recursos");
            }
            if (Math.Round(totalOrigen) != Math.Round(totalNewRecurso))
            {
                throw new Exception("Los montos de los nuevos recursos generados  son diferentes  ");
            }

            using (TransactionScope ts = new TransactionScope())
            {
                
                int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());


                //1 creamos el id de transaccion de agrupado
                EstructuraAgrupado ECA = new EstructuraAgrupado();
                ECA.idMoneda = idMoneda;
                ECA.idEstructuraCosto = idEstructuraCosto;
                ECA.fechaCre = DateTime.Now;
                ECA.usuarioCre = idEmpleadoEmisor;
                ECA.idOrigen = 2;// indica que es desde los presupuesto
                ECA.idObra = idObra;

                _db.EstructuraAgrupados.InsertOnSubmit(ECA);
                _db.SubmitChanges();
                 

                foreach (EstructuraCostoitemsingleInfo itemNew in newECItemList)
                {
                    //actualizamos los valores de  la transaccion
                    if (itemNew.idInternal == 0)
                    {
                        continue;
                    }
                    EstructuraCostoItem ECItem = new EstructuraCostoItem();
                    ECItem.setTCFromMoneda(_db, idMoneda, idObra);
                    decimal tipoCambio = ECItem.tipoCambio.Value;

                    ECItem.addECItem(_db,
                                                            idEstructuraCosto,
                                                            null,
                                                            itemNew.idInsumo,
                                                            itemNew.codigo,
                                                            itemNew.descripcion,
                                                            itemNew.unidad,
                                                            0,
                                                            null,
                                                            true,
                                                            itemNew.cantidad,
                                                            itemNew.precio,
                                                            itemNew.total,
                                                            idMoneda,
                                                            tipoCambio,
                                                             ECA.idInternal,
                                                             idEmpleadoEmisor,
                                                             itemNew.idOrdenCompraItem == 0 ? null : itemNew.idOrdenCompraItem.ToInt2());

                }
                _db.SubmitChanges();


                ///ORIGEN
                ///
                foreach (EstructuraCostoitemReUsoInfo item in reUsoComparativoItemList)
                {
                    //el recurso debe tener disponible y debe ser finalizado
                    EstructuraCostoItem origen =
                        _db.EstructuraCostoItems.Single(p => p.idInternal == item.idInternal);

                    if ((origen.total - origen.totalUso )< item.totalReUso)
                    {
                        string msg = "No debe permitir  montos superiores a lo disponible :" + item.descripcion;
                        throw new Exception(msg);
                    }


                    EstructuraAgrupadoItem itemAgrupado = new EstructuraAgrupadoItem();
                    itemAgrupado.idEstructuraCostoItem = item.idInternal;
                    itemAgrupado.idEstructuraagrupado = ECA.idInternal;
                    itemAgrupado.total = item.totalReUso;
                    _db.EstructuraAgrupadoItems.InsertOnSubmit(itemAgrupado);
                    _db.SubmitChanges();
                    var qtotales=from a in _db.EstructuraAgrupadoItems
                                 where a.idEstructuraCostoItem==item.idInternal
                                 select a;

                    origen.totalReUso = qtotales.Sum(p=>p.total); 
                    origen.bitsel = true; //se tiene que seguir  viendo en los configurados
                    origen.idAgrupadoOrigen = ECA.idInternal;

                }
                _db.SubmitChanges();

                ts.Complete();
                return true;
            }
        }




        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public List<EstructuraCostoitemReUsoInfo> getECItemComparativoFinalizadoListInfo(int idestructuraCosto, 
                                                                            int idMoneda)
        {
            var q = ApplySelect_EstructuraCostoItemConfInfo();
            // luego tiene que ser acualizado  al finalizar el cambio de proceso
            // solo quedar por el  proceso de devolucion

           
            q = q.Where(a => a.idEstructuraCosto == idestructuraCosto 
                            & a.idMoneda==idMoneda
                            & a.bitsel == true);



           var q2 = (from a in q.ToList()
                     where a.bitFinalizadoContrato == true &
                     a.idEstructuraCosto==idestructuraCosto &
                     a.totalDisp>0
                     select new EstructuraCostoitemReUsoInfo    
                     {
                         codigo=a.codigo,
                         Comparativo = a.toolTipResu,
                         descripcion=a.descripcion,
                         unidad=a.unidad,
                         idEstructuraCosto=a.idEstructuraCosto,
                         idInsumo=a.idInsumo,
                         idInternal=a.idInternal,
                         totalDispStr=a.totalDispMon,
                         totalReUsoStr=a.totalDispMon,
                         totalReUso=a.totalDisp,
                         totalDisp = a.totalDisp,

                     }).ToList();


            //agremamos los devueltos

            var q3 = (from a in DbUtil.Db.EstructuraCostoItems
                     where a.idEstructuraCosto == idestructuraCosto
                     & a.ComparativoItemRef != null
                     & a.idMoneda == idMoneda
                     & (a.total - a.totalUso - a.totalReUso) > 0
                     select new EstructuraCostoitemReUsoInfo
                     {
                         codigo = a.codigo,
                         Comparativo = a.ComparativoItem.Comparativo.numDocumento,
                         descripcion = a.descripcion,
                         unidad = a.unidad,
                         idEstructuraCosto = a.idEstructuraCosto.Value,
                         idInsumo = a.idInsumo.Value,
                         idInternal = a.idInternal,
                         
                         totalReUso = a.total.Value-a.totalUso.Value-a.totalReUso.Value,
                         totalDisp = a.total.Value - a.totalUso.Value - a.totalReUso.Value,

                         totalDispStr = String.Format("{0} {1:N}",a.Moneda.simbol, a.total.Value - a.totalUso.Value - a.totalReUso.Value),
                         totalReUsoStr = String.Format("{0} {1:N}", a.Moneda.simbol, a.total.Value - a.totalUso.Value - a.totalReUso.Value),
                                                
                     }).ToList();
            q2.AddRange(q3);

            ////--------------agregamos los que tambien fueron agrupados  y no usados para volverlos a convertir
            //var q4 = (from a in DbUtil.Db.EstructuraCostoItems
            //          where a.idEstructuraCosto == idestructuraCosto
            //          & (a.idAgrupadoDestino!=null?a.EstructuraAgrupado1.idOrigen=2)

            //          & a.idMoneda == idMoneda
            //          & (a.total - a.totalUso - a.totalReUso) > 0
            //          select new EstructuraCostoitemReUsoInfo
            //          {
            //              codigo = a.codigo,
            //              Comparativo = a.ComparativoItem.Comparativo.numDocumento,
            //              descripcion = a.descripcion,
            //              unidad = a.unidad,
            //              idEstructuraCosto = a.idEstructuraCosto.Value,
            //              idInsumo = a.idInsumo.Value,
            //              idInternal = a.idInternal,

            //              totalReUso = a.total.Value - a.totalUso.Value - a.totalReUso.Value,
            //              totalDisp = a.total.Value - a.totalUso.Value - a.totalReUso.Value,

            //              totalDispStr = String.Format("{0} {1:N}", a.Moneda.simbol, a.total.Value - a.totalUso.Value - a.totalReUso.Value),
            //              totalReUsoStr = String.Format("{0} {1:N}", a.Moneda.simbol, a.total.Value - a.totalUso.Value - a.totalReUso.Value),

            //          }).ToList();
            //q2.AddRange(q4);

            return q2;

        }

       

        public bool deleteECItemReAgrupado(
            int idAgrupado)
        {
            using (TransactionScope ts = new TransactionScope())
            {

                dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString);

                //Eliminamos los  item  generados  en la estructura
                var  destino= from a in _db.EstructuraCostoItems
                        where a.idAgrupadoDestino == idAgrupado
                        select a;

                //Eliminamos la estructura 
                foreach (EstructuraCostoItem item in destino)
                {
                    
                    //Verificamos que no este en  usado los item agrupados
                    var comitem = from a in _db.ComparativoItems
                            where a.idEstructuraCostoItem == item.idInternal
                            select a;
                    //verificar si existe comparativos con este ECItem
                    if (comitem.Count()> 0)
                    {
                        
                        throw new Exception("No se puede Eliminar el recurso por encontrarse  utilizado");
                    }

                    //si este fue agrupado para formar otro  recurso
                    if (item.idJuntoPadre !=null)
                    {
                        throw new Exception("No se puede Eliminar el recurso por encontrarse  agrupado a otros recursos  del mismo codigo en recursos configurados");
                    }
                    _db.EstructuraCostoItems.DeleteOnSubmit(item);
                    _db.SubmitChanges();
                }

               
                

                //--------------------------------------------------------------

                var origen = (from e in _db.EstructuraAgrupadoItems
                             where e.idEstructuraagrupado == idAgrupado
                             select e.EstructuraCostoItem).ToList();


                //-------------------------------------------

                //Eliminamos el detalle del agrupado

                var qitem = from a in _db.EstructuraAgrupadoItems
                            where a.idEstructuraagrupado == idAgrupado
                            select a;

                _db.EstructuraAgrupadoItems.DeleteAllOnSubmit(qitem);
                _db.SubmitChanges();


                //----------------------------------

                //Actualizamos los originales
                foreach (EstructuraCostoItem itemdb in origen)
                {

                    var q = from a in _db.EstructuraAgrupadoItems
                            where a.idEstructuraCostoItem == itemdb.idInternal
                            select a;
                    decimal total = 0;
                    if(q.Count()>0)
                        total = q.Sum(p => p.total);
                    EstructuraCostoItem e = _db.EstructuraCostoItems.Single(p => p.idInternal == itemdb.idInternal);


                    e.bitsel = true;
                    e.totalReUso = total;
                    e.idAgrupadoOrigen = null;
   
                     _db.SubmitChanges();
                }




                // eliminamos del agrupado trans
                EstructuraAgrupado agrupado = _db.EstructuraAgrupados.Single(p => p.idInternal == idAgrupado);
                _db.EstructuraAgrupados.DeleteOnSubmit(agrupado);
                _db.SubmitChanges();

                 ts.Complete();

                                return true;
            }

        }


        public bool deleteEstructuraCostoItem(int idEstructuraCostoItem)
        {
            bool result=false;
            dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString);

            EstructuraCostoItem dbECitem = _db.EstructuraCostoItems.Single(p => p.idInternal == idEstructuraCostoItem);

            EstructuraCosto dbEC =_db.EstructuraCostos.Single(p => p.idInternal == dbECitem.idEstructuraCosto);

            Recurso recursodb = new Recurso();
            EstructuraCostoItem dbECitemPadre = new EstructuraCostoItem();
            EstructuraCostoItem dbECitemAbuelo = new EstructuraCostoItem();

            
            var qc= from a in _db.ComparativoItems
                    where a.idEstructuraCostoItem == idEstructuraCostoItem
                       select a;
           if (qc.Count() > 0)
                {
                    throw new Exception("No se puede Eliminar el recurso por encontrarse  utilizado en comparativo");

                }

           
            
            if (dbECitem.idJuntoPadre !=null)
            {
                throw new Exception("El recurso se cuentra incluido al juntar ");
            }




            using (TransactionScope ts = new TransactionScope())
            {

            // buscamos al padre  del  recurso, solo  recorre 2 niveles politica de la empresa

            if (dbECitem.nivel == 1)
            {
                //utiliza el idrecurso del padre
                dbECitemPadre = _db.EstructuraCostoItems.Single(p => p.idInternal == dbECitem.idPadre);
                if (dbECitemPadre.idRecurso == null)
                {
                    throw new Exception("Item pertenece a  una estructura de costo Agrupado,elimine el Agrupado");
                }

                 recursodb =    _db.Recursos.Single(p => p.idInternal == dbECitemPadre.idRecurso);
                //eliminamos item
               _db.EstructuraCostoItems.DeleteOnSubmit(dbECitem);
               _db.SubmitChanges();
                //actualizamos padre en caso de ser 0 se anula  tambien;
               dbECitemPadre.updateMontoDivisionItemPadre(_db);
                // actualizamos el recurso
                recursodb.updateUso(_db);

            }
            if (dbECitem.nivel == 2)
            {
                //utiliza el idrecurso del padre
                dbECitemPadre =
                   _db.EstructuraCostoItems.Single(p => p.idInternal == dbECitem.idPadre);

                dbECitemAbuelo =
                  _db.EstructuraCostoItems.Single(p => p.idInternal == dbECitemPadre.idPadre);

                if (dbECitemAbuelo.idRecurso == null)
                {
                    throw new Exception("Item pertenece a  una estructura de costo Agrupado");
                }
                
                
                recursodb =
                    _db.Recursos.Single(p => p.idInternal == dbECitemAbuelo.idRecurso);


                _db.EstructuraCostoItems.DeleteOnSubmit(dbECitem);
                _db.SubmitChanges();

                dbECitemPadre.updateMontoDivisionItemPadre(_db);
                dbECitemAbuelo.updateMontoDivisionItemPadre(_db);
                  recursodb.updateUso(_db);
 

            }
            if (dbECitem.nivel == 0)
            {
                if (dbECitem.idRecurso == null)
                {
                    throw new Exception("Item pertenece a  una estructura de costo Agrupado");
                }

                recursodb =_db.Recursos.Single(p => p.idInternal == dbECitem.idRecurso);

                _db.EstructuraCostoItems.DeleteOnSubmit(dbECitem);
                _db.SubmitChanges();

                recursodb.updateUso(_db);
 
            }

                      dbEC.updateMontoMonBase(_db);
                    ts.Complete();
                    result = true;
                }

          return result;
            
        }

        public bool juntarEstructuraCostoItem(List<EstructuraCostoItemJuntosInfo> recursoLista)
            {
            using (TransactionScope ts= new TransactionScope())
            { 
                if (recursoLista.Count() <= 1)
                    {
                        throw new Exception("No se puede Juntar. Debe exisitir más Recursos");
                    }

                int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());
                

                using (dbGestionDataContext _db= new dbGestionDataContext(Parametros.strConnString))
                {
                                  
                    //Plantilla para agrupacion de recursos
                    DAL.EstructuraCostoItem ecitem = _db.EstructuraCostoItems.Single(p => p.idInternal == recursoLista.First().idInternal);

                      // si es null el recurso, se debe ingresar el  moneda  y tipo de cambio
                    EstructuraCostoItem ecitemNew= new EstructuraCostoItem();

                    ecitemNew.addECItem(_db,
                        ecitem.idEstructuraCosto.Value,
                        null,
                        ecitem.idInsumo.Value,
                        ecitem.codigo,
                        ecitem.descripcion,
                        ecitem.unidad,
                        0,
                        null,
                        true,
                        0,
                        0,
                        0,
                        ecitem.idMoneda,
                        ecitem.tipoCambio,
                        null,
                        idEmpleadoEmisor,
                        null);


                    // para cada uno de los registros identificados, son actualizados con sus valores 
                    foreach (var a in recursoLista)
                    {

                    //reviso todos los item de ECitem para agruparaquellos que tienen el mismo codigo  
                              //existe disponible
                        EstructuraCostoItem ec = _db.EstructuraCostoItems.Single(p => p.idInternal == a.idInternal);
                        var qc= from aw in _db.ComparativoItems
                               where aw.idEstructuraCostoItem==ec.idInternal
                               select aw;

                        if (qc.Count() > 0)
                        {
                            throw new Exception("No puede agrupar recursos que tienen uso");
                        }

                         //Ingresamos un solo registro que agrupe a todos los demas
                        ec.updateJuntarPadre(_db,ecitemNew.idInternal);
                        
                        
                    }

                    var q= from a in _db.EstructuraCostoItems
                           where a.idJuntoPadre==ecitemNew.idInternal
                           select a;

                    ecitemNew.cantidad = q.Sum(p => p.cantidad - p.cantidadUso).Value;
                    ecitemNew.total = q.Sum(p => p.total - p.totalUso).Value;
                    ecitemNew.precio = Math.Round(ecitemNew.total.Value/ ecitemNew.cantidad.Value, 4);

                    _db.SubmitChanges();
                    ts.Complete();
                }
            }

            return true;
        }

        public bool desjuntarEstructuraCostoItem(int idEstructuraCostoItem, int idusuario)
        {
            using (TransactionScope ts = new TransactionScope())
            {
                using (dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString))
                {


                    EstructuraCostoItem ecitem = _db.EstructuraCostoItems.Single(p => p.idInternal == idEstructuraCostoItem);
                    //verificamos que se  encuetre utilizado

                    if (ecitem.totalUso > 0)
                    {
                        throw new Exception("El recurso se cuentra utilizado");
                    }

                    // todos sus hijos
                    var q = from a in _db.EstructuraCostoItems
                            where a.idJuntoPadre == ecitem.idInternal
                            select a;

                    if (q.Count()==0)
                    {
                        throw new Exception("No es un recurso Agrupado");
                    }
                    
                        foreach (var a in q)
                        {
                            a.bitsel = true;
                            a.idJuntoPadre = null;

                        }

                        _db.EstructuraCostoItems.DeleteOnSubmit(ecitem);
                        _db.SubmitChanges();
                        ts.Complete();
                    
                    
                    return true;
                }
            }


        }

        //public bool updateProveedorAprob(dbGestionDataContext _db ,int idComparativo,int idProveedorApro)
        //{
        //    bool result= false;

        //    // actualiza valores de  cab

        //    // actualiza valores de Det
            

        //    Comparativo comparativo= 
        //        _db.Comparativo.Single(p=>p.idInternal==idComparativo);
             
        //    if (comparativo.idProveedor1==idProveedorApro)
        //    {
        //        comparativo.idProveedorSelec=idProveedorApro;
        //        //comparativo.totalContratado=_db.ComparativoItem.
        //        // actualiza sus totales;
                
        //            var q = from i in _db.ComparativoItem
        //                where i.idComparativo == idComparativo
        //                select i;
        //        foreach (var i in q)
        //        {
        //            i.cantAprob=i.cantidadBase;
        //            i.precioAprob=i.precio1;
        //            i.totalAprob=i.total1;
        //            i.cantUso = 0;
                    
        //            i.totalUso = 0;
        //        }
        //        decimal totalAprob= (from a in _db.ComparativoItem
        //                   where a.idComparativo==idComparativo
        //                             select a).Sum(p => p.total1).Value;

        //        comparativo.totalContratado=totalAprob;
        //        result = true;
        //    }
        //    if (comparativo.idProveedor2 == idProveedorApro)
        //    {
        //        comparativo.idProveedorSelec = idProveedorApro;
        //        //comparativo.totalContratado=_db.ComparativoItem.
        //        // actualiza sus totales;

        //        var q = from i in _db.ComparativoItem
        //                where i.idComparativo == idComparativo
        //                select i;
        //        foreach (var i in q)
        //        {
        //            i.cantAprob = i.cantidadBase;
        //            i.precioAprob = i.precio2;
        //            i.totalAprob = i.total2;
        //        }
        //        decimal totalAprob = (from a in _db.ComparativoItem
        //                              where a.idComparativo == idComparativo
        //                              select a).Sum(p => p.total1).Value;

        //        comparativo.totalContratado = totalAprob;
        //        result = true;
        //    }
        //    if (comparativo.idProveedor3 == idProveedorApro)
        //    {
        //        comparativo.idProveedorSelec = idProveedorApro;
        //        //comparativo.totalContratado=_db.ComparativoItem.
        //        // actualiza sus totales;

        //        var q = from i in _db.ComparativoItem
        //                where i.idComparativo == idComparativo
        //                select i;
        //        foreach (var i in q)
        //        {
        //            i.cantAprob = i.cantidadBase;
        //            i.precioAprob = i.precio3;
        //            i.totalAprob = i.total3;
        //        }
        //        decimal totalAprob = (from a in _db.ComparativoItem
        //                              where a.idComparativo == idComparativo
        //                              select a).Sum(p => p.total1).Value;

        //        comparativo.totalContratado = totalAprob;
        //        result = true;
        //    }
        //    _db.SubmitChanges();
        //    return result;

        //}
        //public bool updateComparativoAprob( int idComparativo, int idEmpleadoAprob)
        //{
        //    bool result = false;
        //    dbGestionDataContext _db = 
        //        new dbGestionDataContext(Parametros.strConnString);

        //    Comparativo comparativo = new Comparativo();

        //    comparativo = _db.Comparativo.Single(p => p.idInternal == idComparativo);
            
        //    comparativo.idEstado=3; // aprobado
        //    comparativo.fechaAprob=DateTime.Now;
        //    comparativo.idEmpleadoAprob= idEmpleadoAprob;


        //    // actualizamos la aprobacion

        //    _db.SubmitChanges();


        //    return result;
        //}
        private IQueryable<EstructuraCostoItemConfInfo> ApplySortG(IQueryable<EstructuraCostoItemConfInfo> q, string sortExpression)
        {
            switch (sortExpression)
            {
                case "idInternal ASC":
                    q = q.OrderBy(b => b.idInternal);
                    break;
                case "idInternal DESC":
                    q = q.OrderByDescending(b => b.idInternal);
                    break;
                case "cantidad ASC":
                    q = q.OrderBy(b => b.cantidad);
                    break;
                case "cantidad DESC":
                    q = q.OrderByDescending(b => b.cantidad);
                    break;
                case "cantidadDisp ASC":
                    q = q.OrderBy(b => b.cantidadDisp);
                    break;
                case "cantidadDisp DESC":
                    q = q.OrderByDescending(b => b.cantidadDisp);
                    break;

                case "cantidadUso ASC":
                    q = q.OrderBy(b => b.cantidadUso);
                    break;
                case "cantidadUso DESC":
                    q = q.OrderByDescending(b => b.cantidadUso);
                    break;


                case "codigo ASC":
                    q = q.OrderBy(b => b.codigo);
                    break;
                case "codigo DESC":
                    q = q.OrderByDescending(b => b.codigo);
                    break;

                case "unidad ASC":
                    q = q.OrderBy(b => b.unidad);
                    break;
                case "unidad DESC":
                    q = q.OrderByDescending(b => b.unidad);
                    break;

                case "descripcion ASC":
                    q = q.OrderBy(b => b.descripcion);
                    break;
                case "descripcion DESC":
                    q = q.OrderByDescending(b => b.descripcion);
                    break;


                case "precio ASC":
                    q = q.OrderBy(b => b.precio);
                    break;
                case "precio DESC":
                    q = q.OrderByDescending(b => b.precio);
                    break;

                case "total ASC":
                    q = q.OrderBy(b => b.total);
                    break;
                case "total DESC":
                    q = q.OrderByDescending(b => b.total);
                    break;

                case "totalDisp ASC":
                    q = q.OrderBy(b => b.totalDisp);
                    break;
                case "totalDisp DESC":
                    q = q.OrderByDescending(b => b.totalDisp);
                    break;
                case "totalReUso ASC":
                    q = q.OrderBy(b => b.totalReUso);
                    break;
                case "totalReUso DESC":
                    q = q.OrderByDescending(b => b.totalReUso);
                    break;
                default:
                    q = q.OrderBy(b => b.idInternal).OrderByDescending(p => p.codigo);
                    break;
            }
            return q;
        }


        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public List<EstructuraCostoItemConfInfo> getEstructuraCostoItemConfig(int idestructuraCosto, string orderBy = default(string))
        {
            var q = ApplySelect_EstructuraCostoItemConfInfo();

            q = q.Where(a => a.idEstructuraCosto == idestructuraCosto
               & a.bitsel == true);

            q = ApplySortG(q, orderBy);

            return q.ToList();
            
        }

        public int Count(int idEstructuraCosto, int idMoneda, string idListYaUtilizado, int startRowIndex, int maximumRows, string sortExpression)
        {
            return _count;
        }

        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public List<EstructuraCostoItemConfInfo> getEstructuraCostoItemConfigDisp(int idestructuraCosto,
                                                                                   int idMoneda,
                                                                                    IEnumerable<int> itemYaUtilizado,
                                                                                    int startRowIndex,
                                                                                    int maximumRows,
                                                                                    string sortExpression)
        {
 
            var q = ApplySelect_EstructuraCostoItemConfInfo();

            var comparadtivolistPentiente = from a in DbUtil.Db.ComparativoItems
                                            where a.Comparativo.idEstado < 3
                                            & a.Comparativo.idEstructuraCosto.Value == idestructuraCosto
                                            
                                            select a.idEstructuraCostoItem;

            q = q.Where(
               a => a.idEstructuraCosto == idestructuraCosto
               & a.bitsel == true
               & a.idMoneda == idMoneda
               & !comparadtivolistPentiente.Contains(a.idInternal)
               & !itemYaUtilizado.Contains(a.idInternal) //estos son los ya ingresados en el comparativo
               & ((a.total - a.totalUso - a.totalReUso) > 0 | 
                       (( (a.cantidad - a.cantidadUso) > 0) )));
            
            _count = q.Count();
            q = ApplySort(q, sortExpression);

            return q.OrderBy(p => p.codigo).ToList();

        }


        public List<OrdenCompraListInfo> getECItemConfigDispAGRPOC(List<EstructuraCostoItemConfInfo> lista, int idProveedor)
        {

            var l = lista.Where(p => p.idOrdenCompraItemRef != null).Select(p=>p.idOrdenCompraItemRef);

            // p


            var ew= (from b in DbUtil.Db.OrdenCompraItems 
                    where l.Contains(b.idInternal)
                    &  b.OrdenCompra.idProveedor==idProveedor
                    select new OrdenCompraListInfo
                    {                                                    
                            idInternal=b.OrdenCompra.idInternal,
                            proveedor=b.OrdenCompra.proveedor,
                            fechaEmision=b.OrdenCompra.fechaEmision.Value,
                            numDocumento=b.OrdenCompra.numDocumento,
                            total=b.OrdenCompra.total.Value,
                            IGVTotal=b.OrdenCompra.IGVTotal.Value,
                            subTotal = b.OrdenCompra.subTotal.Value,
                              simbol=b.OrdenCompra.Moneda1.simbol,
                    }).Distinct().ToList();

       
            return ew;
          }


        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public List<EstructuraCostoItemJuntosInfo> getEstructuraCostoItemJuntosConfig(int idJuntosPadre)
        {

            var q = from a in DbUtil.Db.EstructuraCostoItems
                    where a.idJuntoPadre == idJuntosPadre
                    select new EstructuraCostoItemJuntosInfo 
                    {
                        idInternal=a.idInternal,
                        idPadre = a.idJuntoPadre.Value,
                        codigo=a.Insumo.codigo,
                        descripcion=a.Insumo.descripcion,
                        unidad=a.Insumo.InsumoUnidad.abreviacion,
                        cantidadStr = string.Format("{0:N}", a.cantidad.Value),
                        CantidadDispStr = string.Format("{0:N}", a.cantidad.Value-a.cantidadUso),
                        precioStr=string.Format("{0} {1:N}",a.Moneda.simbol,a.precio.Value),
                        totalStr=string.Format("{0} {1:N}",a.Moneda.simbol,a.total.Value),
                        totalDispStr = string.Format("{0} {1:N}", a.Moneda.simbol, a.total.Value - a.totalUso.Value),
                        total=a.total.Value                     };
            return q.ToList();
            
        }

        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public List<EstructuraCostoItemJuntosInfo> getEstructuraCostoItemEqualCodigo(int idJuntosPadre)
        {
            EstructuraCostoItem ecitem =
                DbUtil.Db.EstructuraCostoItems.Single(p => p.idInternal == idJuntosPadre);

              
                var q = from a in DbUtil.Db.EstructuraCostoItems
                        where a.idEstructuraCosto == ecitem.idEstructuraCosto &
                        a.bitsel == true 
                        & a.codigo == ecitem.codigo 
                        & a.idMoneda == ecitem.idMoneda
                        & a.totalUso == 0
                        select  new EstructuraCostoItemJuntosInfo
                        {
                            cantidadStr=string.Format("{0:N4}",a.cantidad.Value),
                             codigo=a.codigo,
                             descripcion=a.descripcion,
                             idInternal=a.idInternal,
                            precioStr = string.Format("{0} {1:N4}", a.Moneda.simbol,a.precio.Value),
                             total=a.total.Value,
                            totalStr = string.Format("{0}{1:N4}", a.Moneda.simbol,a.total.Value),
                             unidad=a.unidad,
                             simbolMoneda=a.Moneda.simbol
                         };

           
            return q.ToList();

        }
         


        
        //[DataObjectMethod(DataObjectMethodType.Select, false)]
        //public void getEstructuraCostoItemRecurso(int idestructuraCosto)
        //{




        //    //muestra los recursos nivel o y  los agrupados
        //    var q = from a in DbUtil.Db.view_EstructuraCostoItem
        //            where a.idEstructuraCosto == idestructuraCosto &
        //                      a.idPadre == null & 
        //                      a.idAgrupadoOrigen == null &
        //                      a.nivel == 0 & (a.nivel > -1)
        //            select a;



            

        //    // tambien quitar el padres de  juntos
        //    //traemos los padres juntos
        //    //aqui los que tienen padre
        //    var qw = from a in DbUtil.Db.view_EstructuraCostoItem
        //             where a.idEstructuraCosto == idestructuraCosto &
        //             a.idJuntoPadre != null &
        //             a.TotalDisp > 0
        //             select a;

        //    if (qw.Count() > 0)
        //    {
        //        foreach (var i in qw.ToList())
        //        {
                    
        //            //ecitemList.RemoveAll(e => e.idInternal == i.idJuntoPadre);
        //        }
        //    }


        //    var qqq = from a in DbUtil.Db.EstructuraCostoItems
        //            where a.idJuntoPadre != null & a.idEstructuraCosto == idestructuraCosto
        //            select new EstructuraCostoItemJuntosInfo 
        //            {
        //                idInternal=a.idInternal,
        //                idPadre=a.idPadre.Value,
        //                codigo=a.Insumo.codigo,
        //                descripcion=a.Insumo.descripcion,
        //                unidad=a.Insumo.InsumoUnidad.abreviacion,
        //                cantidad = string.Format("{0:N}", a.cantidad.Value),
        //                cantidadDisp = string.Format("{0:N}", a.cantidad.Value-a.cantidadUso.Value),
        //                precioMon=string.Format("{0} {1:N}",a.Moneda.simbol,a.precio.Value),
        //                totalMon=string.Format("{0} {1:N}",a.Moneda.simbol,a.total.Value),
        //                totalDispMon=string.Format("{0} {1:N}",a.Moneda.simbol,(a.total.Value-a.totalUso.Value))
        //             };
        //   // return q.ToList();
            
        //}



        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public IEnumerable<EstructuraCostoitemNivelInfo> getEstructuraCostoItemNivel1(int idEstructuraCostoItem)
        {
            //nivel 1
            return (from a in DbUtil.Db.EstructuraCostoItems
                    where a.idPadre == idEstructuraCostoItem &
                          a.nivel == 1
                    select new EstructuraCostoitemNivelInfo
                    {
                        bitSel=a.bitsel.Value,
                        cantidadStr=String.Format("{0:N}", a.cantidad.Value),
                        cantidadUsoStr = String.Format("{0:N}", a.cantidad.Value),
                        codDescripcion = String.Format("{0}-{1}",a.Insumo.codigo,a.Insumo.descripcion),
                        codigo=a.codigo,
                        descripcion=a.descripcion,
                        idEstructuraCosto=a.idEstructuraCosto.Value,
                        idInsumo=a.idInsumo.Value,
                        idInternal=a.idInternal,
                        idPadre=a.idPadre.Value,
                        nivel=a.nivel.Value,
                        precioStr=String.Format("{0} {1:N}",a.Moneda.simbol,a.precio.Value),
                        totalStr = String.Format("{0} {1:N}", a.Moneda.simbol, a.total.Value),
                        totalUsoStr = String.Format("{0} {1:N}", a.Moneda.simbol, a.totalUso.Value),
                        unidad=a.Insumo.InsumoUnidad.abreviacion
                        
                    });

            

        }

         [DataObjectMethod(DataObjectMethodType.Select, false)]
        public IEnumerable<EstructuraCostoitemNivelInfo> getEstructuraCostoItemNivel2(int idEstructuraCostoItem)
        {
            //nivel 1
            return (from a in DbUtil.Db.EstructuraCostoItems
                    where a.idPadre == idEstructuraCostoItem &
                          a.nivel == 2
                    select new EstructuraCostoitemNivelInfo
                    {
                        bitSel=a.bitsel.Value,
                        cantidadStr=String.Format("{0:N}", a.cantidad.Value),
                        cantidadUsoStr = String.Format("{0:N}", a.cantidad.Value),
                        codDescripcion = String.Format("{0}-{1}",a.codigo,a.descripcion),
                        codigo=a.Insumo.codigo,
                        descripcion=a.Insumo.descripcion,
                        idEstructuraCosto=a.idEstructuraCosto.Value,
                        idInsumo=a.idInsumo.Value,
                        idInternal=a.idInternal,
                        idPadre=a.idPadre.Value,
                        nivel=a.nivel.Value,
                        precioStr=String.Format("{0} {1:N}",a.Moneda.simbol,a.precio.Value),
                        totalStr = String.Format("{0} {1:N}", a.Moneda.simbol, a.total.Value),
                        totalUsoStr = String.Format("{0} {1:N}", a.Moneda.simbol, a.totalUso.Value),
                        unidad=a.Insumo.InsumoUnidad.abreviacion
                        
                    });

            

        }



         private IQueryable<EstructuraCostoitemRecursoInfo> ApplySortG(IQueryable<EstructuraCostoitemRecursoInfo> q, string sortExpression)
         {
             switch (sortExpression)
             {
                 case "idInternal ASC":
                     q = q.OrderBy(b => b.idInternal);
                     break;
                 case "idInternal DESC":
                     q = q.OrderByDescending(b => b.idInternal);
                     break;
                 case "codPartida ASC":
                     q = q.OrderBy(b => b.codPartida);
                     break;
                 case "codPartida DESC":
                     q = q.OrderByDescending(b => b.codPartida);
                     break;

                 case "abreviacion ASC":
                     q = q.OrderBy(b => b.abreviacion);
                     break;
                 case "abreviacion DESC":
                     q = q.OrderByDescending(b => b.abreviacion);
                     break;
                 case "codigo ASC":
                     q = q.OrderBy(b => b.codigo);
                     break;
                 case "codigo DESC":
                     q = q.OrderByDescending(b => b.codigo);
                     break;

                 case "descripcion ASC":
                     q = q.OrderBy(b => b.descripcion);
                     break;
                 case "descripcion DESC":
                     q = q.OrderByDescending(b => b.descripcion);
                     break;


                 case "unidad ASC":
                     q = q.OrderBy(b => b.unidad);
                     break;
                 case "unidad DESC":
                     q = q.OrderByDescending(b => b.unidad);
                     break;


                 case "cantidad ASC":
                     q = q.OrderBy(b => b.cantidad);
                     break;
                 case "cantidad DESC":
                     q = q.OrderByDescending(b => b.cantidad);
                     break;


                 case "precio ASC":
                     q = q.OrderBy(b => b.precio);
                     break;
                 case "precio DESC":
                     q = q.OrderByDescending(b => b.precio);
                     break;

                 case "total ASC":
                     q = q.OrderBy(b => b.total);
                     break;
                 case "total DESC":
                     q = q.OrderByDescending(b => b.total);
                     break;
                 default:
                     q = q.OrderBy(b => b.idInternal).OrderByDescending(p => p.codigo);
                     break;
             }
             return q;
         }


          [DataObjectMethod(DataObjectMethodType.Select, false)]
        public List<EstructuraCostoitemRecursoInfo> getEstructuraCostoItemNivel0(int idEstructuraCosto, 
                                                                            string orderBy = default(string))
        {
            //nivel 0
            List<EstructuraCostoitemRecursoInfo> ecitemList = new List<EstructuraCostoitemRecursoInfo>();

              //quitamos los Reusados que estan en la misma DB
              var qreuso= from a in DbUtil.Db.EstructuraAgrupadoItems
                     where a.EstructuraAgrupado.idEstructuraCosto==idEstructuraCosto
                     select a.EstructuraCostoItem.idInternal;
              //debido a que idAgrupacion destino ya no se utiliza  30/01/2012

            //muestra los recursos nivel o y  los agrupados
            var q = from a in DbUtil.Db.EstructuraCostoItems
                    where a.idEstructuraCosto == idEstructuraCosto &
                              a.idPadre == null 
                              & a.ComparativoItemRef==null
                              &!qreuso.Contains(a.idInternal)                               &
                              a.nivel == 0 & (a.nivel.Value > -1)
                              orderby a.idInternal
                    select new EstructuraCostoitemRecursoInfo
                    {
                        abreviacion=a.Recurso.Partida.Presupuesto.abreviacion,
                        bitSel=a.bitsel.Value,
                        cantidad=a.cantidad.Value,
                        cantidadUso=a.cantidadUso.Value,
                        codigo= a.Insumo.descripcion,
                        descripcion=a.descripcion,
                        codDesPartida=String.Format("{0}-{1}",a.Recurso.Partida.codigo,a.Recurso.Partida.descripcion),
                        idAgrupadoDestino=a.idAgrupadoDestino,
                        idInternal=a.idInternal,
                        idJuntoPadre=a.idJuntoPadre,
                        idPresupuesto=a.Recurso.Partida.idPresupuesto,
                        idRecurso=a.idRecurso.Value,
                        precio=a.precio.Value,
                        precioMon=String.Format("{0} {1:N}",a.Moneda.simbol,a.precio.Value),
                        total=a.total.Value,
                        totalMon=String.Format("{0} {1:N}",a.Moneda.simbol,a.total.Value),
                        unidad=a.Insumo.InsumoUnidad.abreviacion,
                        };

            

            // tambien quitar el padres de  juntos
            //traemos los padres juntos

            var qw = (from a in DbUtil.Db.EstructuraCostoItems
                     where a.idEstructuraCosto == idEstructuraCosto &
                     a.idJuntoPadre != null &
                     a.total-a.totalUso > 0
                     select a.idJuntoPadre).Distinct();

            //aqui los que tienen padre
            var qqq = from a in q
                      where !qw.Contains(a.idInternal)
                      select a;

              //segun orden 

            var qqqq = ApplySortG(qqq, orderBy);

            return qqqq.ToList();            


        }



        [DataObjectMethod(DataObjectMethodType.Select, false)]
          public bool PartirItemConfigurado(int idEstructuraCostoItem)
          {
            int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());

              bool result = false;

              

              var q = this.ApplySelect_EstructuraCostoItemConfInfo();
              q.Where(p => p.idInternal == idEstructuraCostoItem);

              EstructuraCostoItemConfInfo ECItem = q.First();
            decimal CantidadDisp =ECItem.cantidad-ECItem.cantidadUso;
            decimal totalDisp =ECItem.cantidad-ECItem.totalUso;
            //validamos su  uso
            // debe de estar cancelado el comparativo , segun su uso

              if (ECItem.bitFinalizadoContrato)
              {
                  EstructuraCostoItem ecitemNew = new EstructuraCostoItem();
                  

                  using (TransactionScope ts = new TransactionScope())
                  {
                      dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString);
                      ecitemNew.addECItem(_db,
                          ECItem.idEstructuraCosto,
                          null,
                          ECItem.idInsumo,
                          ECItem.codigo,
                          ECItem.descripcion,
                          ECItem.unidad,
                          0,
                          ECItem.idInternal,
                          true,
                          CantidadDisp,
                          ECItem.precio,
                          totalDisp,
                          ECItem.idMoneda,
                          ECItem.tipoCambio,
                          null,
                          idEmpleadoEmisor,
                          null);
                      
                      
                      // el padre lo sub utilizamos lo actualizamos

                      _db.SubmitChanges();



                      ts.Complete();
                      result = true;
                  }


              }
              else
              {

                  throw new Exception("No  puede ser Partido Verifique estado del Comparativo ");
              }
             

            
              return result;

          }


        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public IEnumerable< EstructuraCostoItemConfInfo> getEstrucCostoItemConfigFinalizados(int idEstructuraCostoItem)
        {

            var q = this.ApplySelect_EstructuraCostoItemConfInfo();
            q=q.Where(p => p.bitFinalizadoContrato==true);

            return q;

        }


        private IQueryable<EstructuraCostoItemConfInfo> ApplySelect_EstructuraCostoItemConfInfo()
        {

            var q = from a in DbUtil.Db.EstructuraCostoItems
                    select new EstructuraCostoItemConfInfo 
                    {
                        idInternal=a.idInternal,
                        codigo=a.Insumo.codigo,
                        descripcion=a.Insumo.descripcion,
                        unidad=a.Insumo.InsumoUnidad.abreviacion,
                        cantidadStr = string.Format("{0:N}", a.cantidad.Value),
                        cantidadUsoStr = string.Format("{0:N}", a.cantidadUso.Value),
                        cantidad = a.cantidad.Value,
                        cantidadUso = a.cantidadUso.Value,
                        cantidadDisp = a.cantidad.Value-a.cantidadUso.Value,
                        precioMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.precio.Value),
                        totalMon = string.Format("{0} {1:N} ", a.Moneda.simbol, a.total.Value),
                        totalUsoMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.totalUso.Value),
                        total = a.total.Value,
                        totalUso =a.totalUso.Value,
                        idInsumo=a.idInsumo.Value,
                        idMoneda=a.idMoneda.Value,
                        tipoCambio=a.tipoCambio.Value,
                        bitsel=a.bitsel.Value,
                        idEstructuraCosto=a.idEstructuraCosto.Value,
                        totalReUso=a.totalReUso.Value,
                        totalReUsoMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.totalReUso.Value),
                        totalDispMon = string.Format("{0} {1:N}", a.Moneda.simbol, (a.total.Value - a.totalUso.Value-a.totalReUso).Value),
                        totalDisp = (a.total.Value - a.totalUso.Value - a.totalReUso.Value),
                        precio=a.precio.Value,
                        ECItemRef=a.ComparativoItemRef,
                        idOrdenCompraItemRef=a.idOrdenCompraItemRef,
                        simbol=a.Moneda.simbol

                   };
            return q;
        }





        /// <summary>
        /// Cambia la Orden de Compra segun la moneda que se requiere de acuerdo al tipo de cambio 
        /// de la obra
        /// </summary>
        /// <param name="idOrdenCompraItem"></param>
        /// <param name="idMonedaEC"></param>
        public EstructuraCostoitemsingleInfo GetFromOCItem(int idOrdenCompraItem, int idMonedaEC,decimal tipoCambioOBRADOL,
            string simbolOBRABOL,string simbolMonedaBase)
        {
            var ocitem = DbUtil.Db.OrdenCompraItems.Single(p => p.idInternal == idOrdenCompraItem);
          
            var nuevo = new EstructuraCostoitemsingleInfo(Parametros.GenerarID(),
                                                        ocitem.idInsumo.Value,
                                                        ocitem.Insumo.codigo,
                                                        ocitem.Insumo.descripcion,
                                                        ocitem.Insumo.InsumoUnidad.abreviacion,
                                                        ocitem.OrdenCompra.Obra.incluyeIGV == true ? ocitem.precioInclIGV.Value : ocitem.precioNoIGV.Value,
                                                        ocitem.cantidad.Value,
                                                        ocitem.OrdenCompra.Obra.incluyeIGV == true ? ocitem.subMontoIGV.Value : ocitem.subMonto.Value,
                                                        ocitem.idOrdenCompra.Value,
                                                        ocitem.idInternal,
                                                        ocitem.OrdenCompra.numDocumento,
                                                        ocitem.OrdenCompra.Moneda1.simbol,
                                                        ocitem.OrdenCompra.idMoneda.Value);

            nuevo.cambiarMoneda(idMonedaEC, tipoCambioOBRADOL, simbolOBRABOL, simbolMonedaBase);

            return nuevo;

        }




        public EstructuraCostoItemRecursoInfo GetSaldoNotaCredito(int idObra,int idMonedaMuestra)
        {
            //---------------------agrego los M ontos de la nota de Credito/convertimos segun moneda------//
            Obra obra = DbUtil.Db.Obras.Single(p => p.idInternal == idObra);
            Moneda moneda=DbUtil.Db.Monedas.Single(p=>p.idInternal==idMonedaMuestra);


            decimal totalNC = 0;
            decimal total = 0;
            decimal totalUSOSol = 0;
            decimal totalUSODol = 0;

            var sol = from a in DbUtil.Db.RecepcionDocs
                      where a.idTipoDocumento == 6 & a.idObra == idObra
                      select a;

            var EcItemSol = from a in DbUtil.Db.EstructuraCostoItems
                            where a.idInsumo == 12954
                            & a.EstructuraCosto.idObra == idObra
                            & a.idMoneda == 3
                            select a;

            var EcItemDol = from a in DbUtil.Db.EstructuraCostoItems
                            where a.idInsumo == 12954
                            & a.EstructuraCosto.idObra == idObra
                            & a.idMoneda == 4
                            select a;


            if (sol.Count() > 0)
            {
                totalNC = obra.incluyeIGV == false ? sol.Sum(p => p.netoMN).Value : sol.Sum(o => o.totalMN).Value; //todo en soles
            }
            if (EcItemSol.Count() > 0)
            {
                //segun moneda sumanos lo restante en soles
                totalUSOSol = EcItemSol.Sum(p => p.total).Value;

            }
            if (EcItemDol.Count() > 0)
            {
                //segun moneda sumanos lo restante en soles
                totalUSODol = EcItemDol.Sum(p => p.total).Value;

            }

            total = Math.Abs(totalNC) - totalUSOSol - (totalUSODol * obra.tipoCambio.Value); ///soles
            decimal final=Math.Round((idMonedaMuestra==3)?total:(total/Convert.ToDecimal(obra.tipoCambio)),2);
            //idMonedaMuestra

     
            ///
            //creamos el registro
            Insumo insumo = DbUtil.Db.Insumos.Single(p => p.idInternal == 12954);
            EstructuraCostoItemRecursoInfo nuevo = new EstructuraCostoItemRecursoInfo();
            nuevo.moneda=moneda;
            nuevo.idInternal = Parametros.GenerarID();
            nuevo.idInsumo = insumo.idInternal;
            nuevo.descripcion = insumo.descripcion;
            nuevo.cantidad = 1;
            nuevo.unidad = insumo.InsumoUnidad.abreviacion;
            nuevo.precio = final;
            nuevo.total = final;
            nuevo.codigo = insumo.codigo;
            nuevo.tipoCambio = Convert.ToDecimal(obra.tipoCambio);
            nuevo.cantidadStr = String.Format("{0}", 1);
            nuevo.precioStr = string.Format("{0} {1:N4}", moneda.simbol, final);
            nuevo.totalStr = string.Format("{0} {1:N2}", moneda.simbol, final);
                                
            return nuevo;

        }


    }
}
